/*
 *   Copyright 2021 zzh
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 */

package com.aduib.boot.common.serialization.kryo.utils;

import com.aduib.boot.common.serialization.support.SerializableClassRegistry;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;

import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @description: AbstractKryoFactory
 * @author: zzh
 * @date: 2021/10/11 15:07
 */
public abstract class AbstractKryoFactory {

  private final Set<Class<?>> serializationClasss = new LinkedHashSet<>();

  private volatile boolean kryoCreated;

  public void registerClass(Class<?> clazz) {
    if (kryoCreated) {
      throw new IllegalStateException("Can't register class after creating kryo instance");
    }
    serializationClasss.add(clazz);
  }

  public Kryo createKryo() {
    if (!kryoCreated) {
      kryoCreated = true;
    }
    Kryo kryo = new CompatibleKryo();
    kryo.setRegistrationRequired(false);
    for (Class<?> clazz : serializationClasss) {
      kryo.register(clazz);
    }

    SerializableClassRegistry.getRegisteredClasses().forEach((clazz, ser) -> {
      if (ser == null) {
        kryo.register(clazz);
      } else {
        kryo.register(clazz, (Serializer<?>) ser);
      }
    });

    return kryo;
  }

  public abstract Kryo getKryo();

  public abstract void returnKryo(Kryo kryo);
}
